/*
 *  This file is part of WWWPal.
 *
 *  Copyright (C) 2003  Dr. John Punin, Department of Computer Science
 *  Rensselaer Polytechnic Institute
 *
 *  WWWPal is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  WWWPal is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "client.h"
#include "dirpartition.h"
#include "partition.h"
#include "report_map.h"

typedef struct _cluster_info {
  char *graphfile;
  int nnodes;
  char *vlabel;
  char *vtitle;
} iCluster;


iCluster *
new_icluster(char *fn, int nn, char *vl, char *vt)
{
  iCluster *ic = (iCluster *)calloc(1, sizeof(iCluster));
  GRStrAllocCopy(ic->graphfile, fn);
  ic->nnodes = nn;
  GRStrAllocCopy(ic->vlabel, vl);
  GRStrAllocCopy(ic->vtitle, vt);
  return ic;
}

void
delete_icluster(iCluster *ic)
{
  free(ic->graphfile); ic->graphfile = NULL;
  free(ic->vlabel); ic->vlabel = NULL;
  free(ic->vtitle); ic->vtitle = NULL;
  free(ic); ic = NULL;
}

void
delete_list_clusters(LNode_type *lclusters)
{
  LNode_type *ptr = NULL;
  for(ptr = lclusters->back; ptr!= lclusters ; ptr= ptr->back)
  {
    iCluster *cur = (iCluster *)ptr->info;
    if(cur)
      delete_icluster(cur);
  }
  Delete_all_list(lclusters);
}

void 
copy_root(tgrFrame *tgf, tgrFrame *ntgf);
PNODE
find_orig_root(tgrFrame *maptgf,tgrFrame *tgf);
void
select_vertices_by_directory(tgrFrame *tgf,int mn);

void
construct_map_clusters(mainFrame *mf,tgrFrame *tgf,Hashtable_type FrameTable);

void
partition_dir_cluster(mainFrame *mf, tgrFrame *tgf, int mn,Hashtable_type FT,
		      LNode_type *lclusters);

int 
dir_partition_algorithm(mainFrame *mf, int mn)
{  
  int count = count_llist(mf->ltgr_frame);
  tgrFrame *tgf = (tgrFrame *)mf->cur_node_tgf->info;
  tgrFrame *btgr = NULL;
  int ins = 0;
  int min_nodes;
  Hashtable_type FrameTable;
  LNode_type *lclusters;
  if(mn != 0)
    min_nodes = mn;
  else
    min_nodes = MIN_CLUSTER_NODES;

  if(count > 1)
    {
    fprintf(stderr,"Sorry, there are more than one graph to be partitioned\n");
      return 0;
    }

  init_hash_table(FrameTable);

  lclusters  = init_linked_list();

  ins = select_shape_vertices(tgf->gf,BOX); 
  printf("%d HTML nodes \n", ins);
  btgr = execute_simple_browsing(mf);

  copy_root(tgf,btgr);

  move_cur_to_tgf(mf, btgr);

  partition_dir_cluster(mf,btgr,min_nodes,FrameTable,lclusters);

  printf("Constructing map\n");

  construct_map_clusters(mf,btgr,FrameTable);

  erase_frame(mf, btgr);

  Delete_hash_table(FrameTable);

  delete_list_clusters(lclusters);
  printf("FINISHED\n");
  return 0;
}

void
partition_connected_components(mainFrame *mf, tgrFrame *tgf, int mn,
			       Hashtable_type FT,LNode_type *lclusters)
{
    int ncomponents = compute_connected_components(tgf->gf);
    int i;
    tgrFrame *btgf = NULL;

    if(ncomponents <= 1)
    {
	printf("ONE component \n");
	partition_dir_cluster(mf,tgf,mn,FT,lclusters);
    }
    else
    {
	for(i = 1; i <= ncomponents; i++)
	{
	  int nsel = 0;
	  nsel = select_i_connected_component_vertices(tgf->gf, i);
          printf("%d nodes selected %d component from %d components\n",
		 nsel, i,ncomponents);
	  btgf = execute_simple_browsing(mf);
	  copy_root(tgf,btgf);
	  move_cur_to_tgf(mf, btgf);
	  partition_dir_cluster(mf, btgf,mn,FT,lclusters);
	  erase_frame(mf, btgf);
	  move_cur_to_tgf(mf, tgf);
	  deselect_all_nodes(tgf->gf);
	}
    }
}

void
hash_nodes_by_frame(tgrFrame *tgf, Hashtable_type FT,LNode_type *lclusters)
{
  iCluster *ic = NULL;
  LNode_type *ptr = NULL;
  LNode_type *lvertices = get_list_vertices(tgf->gf);
  char *nf = tgf->filename;
  int nn = get_count_vertex(tgf->gf);
  PNODE v = tgf->root;
  char *vl = NULL, *vt = NULL;
  if(v) 
  {
     vl = get_label_vertex(v);
     vt = (char *) get_attribute(v,"title");
  }
  ic = new_icluster(nf,nn,vl,vt);

  printf("Hashing %s file\n", nf);
  for(ptr = lvertices->back; ptr != lvertices ; ptr = ptr->back)
  {
    PNODE v = (PNODE)ptr->info;
    insert_hash_info(FT,get_label_vertex(v),(char *)ic);
  }
  Insert_linked_list(lclusters, create_new_node_llist((char *)ic));
}

void
save_cluster(mainFrame *mf,tgrFrame *tgf, Hashtable_type FT, 
	     LNode_type *lclusters)
{
    char *nf = NULL;
    if(!tgf->filename)
	tgf->filename = create_new_name(mf);
    nf= change_end_name(tgf->filename,"gr", "html");
    report_map_site(mf, tgf, nf, tgf->root, 0,0,0);
    save_current_graph(tgf);
    hash_nodes_by_frame(tgf,FT,lclusters);
    free(nf); nf = NULL;
}

void 
split_graph(mainFrame *mf, tgrFrame *tgf, int mn, Hashtable_type FT, 
		 LNode_type *lclusters)
{
  int cnodes;
  int snodes = count_llist(get_list_selected_vertices(tgf->gf));

  tgrFrame *btgf = execute_simple_browsing(mf);
  move_cur_to_tgf(mf, btgf);
  copy_root(tgf,btgf);
  printf("Partition %d nodes\n", snodes);
  partition_connected_components(mf, btgf,mn,FT,lclusters);
  erase_frame(mf, btgf);
  cnodes = select_complement(tgf->gf);
  printf("Partition Complement %d nodes\n", cnodes);
  move_cur_to_tgf(mf, tgf);
  btgf = execute_simple_browsing(mf);
  copy_root(tgf,btgf);
  move_cur_to_tgf(mf, btgf);
  partition_connected_components(mf, btgf,mn,FT,lclusters);
  erase_frame(mf, btgf);
}

void
partition_dir_cluster(mainFrame *mf, tgrFrame *tgf, int mn,Hashtable_type FT,
		      LNode_type *lclusters)
{
   int nnodes = get_count_vertex(tgf->gf);
   int snodes = 0;

   if(!tgf->root)
   {
     tgf->root = choose_best_root_vertex(tgf);
     snodes = count_llist(get_list_selected_vertices(tgf->gf));
   }
   else
   {
     compute_tree_graph(tgf->gf,tgf->root);
     snodes = select_tree(tgf->gf,tgf->root);
   }

   if(snodes != nnodes)
   {
     split_graph(mf,tgf,mn, FT,lclusters);
     return;
   }
   else
   {
     deselect_all_nodes(tgf->gf);
   }

   if(nnodes <= mn)
   {
     save_cluster(mf,tgf,FT,lclusters);
     return;
   }
   
   select_vertices_by_directory(tgf,mn);
   snodes = count_llist(get_list_selected_vertices(tgf->gf));

   printf("Selected nodes %d out of %d \n", snodes, nnodes);

   if(snodes != nnodes)
   {	
     split_graph(mf,tgf,mn, FT,lclusters);
   }
   else
   {
     save_cluster(mf,tgf,FT,lclusters);
   }
}

int
tgr_partition_url(char *url, int *npos)
{
  int i,j=0,ulen = url ? strlen(url) : 0;

  if(ulen == 0)
    return 0;
  for(i = ulen; i>8 ; i--)
    {
      if(url[i]=='/')
	npos[j++] = i;
    }
  npos[j] = -1;
  return j;
}

typedef struct list_item_pattern {
  char *pattern;
  int count;
  int level;
} PatItem;

PatItem *
find_pattern_item(LNode_type *lpattern,char *label)
{
  LNode_type *ptr = NULL;  
  for(ptr = lpattern->back; ptr!= lpattern ; ptr= ptr->back)
  {
    PatItem *cur = (PatItem *)ptr->info;
    if(cur->pattern && !strcmp(cur->pattern,label))
       return cur;
  }
  return NULL;
}
PatItem *
add_pattern_item(LNode_type *lpattern,char *label,int level)
{
  PatItem *pat_node = (PatItem *)calloc(1, sizeof(PatItem));
  if(!pat_node) {
    fprintf(stderr,"Out of Memory add_pattern_item\n");
    abort();
  }
  pat_node->count = 1;
  pat_node->level = level;
  GRStrAllocCopy(pat_node->pattern,label);
  Insert_linked_list(lpattern, create_new_node_llist((char *)pat_node));
  return pat_node;
}

void 
delete_pattern_list(LNode_type *lpattern)
{
  LNode_type *ptr = NULL;
  for(ptr = lpattern->back; ptr!= lpattern ; ptr= ptr->back)
  {
    PatItem *cur = (PatItem *)ptr->info;
    if(cur->pattern)
    {
      /*printf("Deleting %d %s %d\n", cur->count,cur->pattern,cur->level);*/
      free(cur->pattern);
      cur->pattern = NULL;
    }
    free(cur); cur = NULL;
  }
  Delete_all_list(lpattern);
}

LNode_type *
construct_pattern_names(LNode_type *lver, int *glevel)
{
  LNode_type *ptr = NULL;
  LNode_type *lpattern = init_linked_list();
  PatItem *vi;
  *glevel = 0;
  for(ptr = lver->back; ptr!= lver ; ptr= ptr->back)
    {
      PNODE v = (PNODE)ptr->info;
      int i=0,npos[100];
      int max_level = 0;
      char *vlabel = get_label_vertex(v);

      /* npos saves the position of the '/' in the URL */
      if(!(max_level = tgr_partition_url(vlabel, &(npos[0]))))
	  continue;
      if(max_level > *glevel)
	  *glevel = max_level;
      for(;npos[i]!=-1 && i< 100; i++)
      {
	int es = npos[i];
	char * nlabel = malloc(es+2);
	if(!nlabel) {
	  fprintf(stderr,"Out of Memory construct_pattern_names\n");
	  abort();
	}		
	strncpy(nlabel,vlabel, es+1);
	nlabel[es+1]='\0';
	vi = find_pattern_item(lpattern,nlabel);
	if(!vi)
	{
	  vi = add_pattern_item(lpattern,nlabel,max_level--);
	}
	else
	{
	  (vi->count)++;
	}
	free(nlabel); nlabel = NULL;
      }	
    }
  return lpattern;
}

void
select_nodes_by_pattern(tgrFrame *tgf, LNode_type *lvertices, 
			  LNode_type *lpattern, int mn)
{
  int i = 0;
  int count = 1;
  LNode_type *ptr = NULL;

  while(count != 0)
  {
     char *pattern = NULL;
     count = 0;
     i++;

     for(ptr = lpattern->next; ptr != lpattern ; ptr = ptr->next)
     {
       PatItem *cur = (PatItem *)ptr->info;

       if(cur->level == i)
	   count++;
     }

     if(count > 1)
     {
       PatItem **items = (PatItem **)calloc(count, sizeof(PatItem*));
       int maxc = 0, j = 0, l = 0;

       if(!items) {
	   fprintf(stderr,"Out of Memory deselect_nodes_by_pattern\n");
	   abort();
       }

       for(ptr = lpattern->next; ptr != lpattern ; ptr = ptr->next)
       {
	 PatItem *cur = (PatItem *)ptr->info;
	 if(cur->level == i)
	     items[j++] = cur;
       }

       for(l = 0 ; l < j ; l++) 
       {
	 int r = 0,k = 0;
	 int imax = 0, max_count = 0;
	 for(r = 0; r < j ; r++)
	     if(items[r])
		 break;
	 
	 if(!items[r])
	   break;

	 imax = r;
	 max_count = items[r]->count;
	 for(k = 1; k< j ; k++)
	 {
	     /*printf("Items %d %d %s \n", items[k]->level,items[k]->count, 
	       items[k]->pattern);*/
	   if(items[k] && items[k]->count > max_count)
	   {
	     max_count = items[k]->count;
	     imax = k;
	   }
	 }
	 printf("MAXIMUM %d %d %s \n", items[imax]->level,items[imax]->count, 
		items[imax]->pattern);


	 /* I can improve this algorithm merging directories */
	 pattern = items[imax]->pattern;

	 printf("pattern is %s\n", pattern);

	 for(ptr = lvertices->back; ptr != lvertices ; ptr = ptr->back)
	 {
	   PNODE v = (PNODE)ptr->info;
	   int len = strlen(pattern);

	   if(!strncmp(get_label_vertex(v),pattern,len))
	   {
	     if(!is_vertex_selected(v))
		 select_vertex(v,tgf->gf);
	   }			
	 }

	 maxc = select_max_component_of_selected_vertices(tgf->gf);
	 printf("Maximum component is %d, %d\n", maxc, mn);
	 

	 if(maxc >= mn) 
	 {
	   free(items); items = NULL;
	   return;
	 }
	 else
	 {
	   deselect_all_nodes(tgf->gf);
	 }
       }
       free(items); items = NULL;
     }
  }
  select_all_nodes(tgf->gf);
}


void
select_vertices_by_directory(tgrFrame *tgf,int mn)
{
  LNode_type *lvertices = get_list_vertices(tgf->gf);	
  int max_level = 0;
  LNode_type *lpattern = construct_pattern_names(lvertices,&max_level);
  printf("Before refining %d nodes\n",get_count_vertex(tgf->gf));
  select_nodes_by_pattern(tgf,lvertices,lpattern,mn);
  printf("After refining %d nodes\n",
	 count_llist(get_list_selected_vertices(tgf->gf)));
  delete_pattern_list(lpattern);
}

#define NORM 0
#define MAX_ITER 30

PNODE
choose_best_source_node(tgrFrame *tgf)
{
  PNODE root = NULL;
  LNode_type *lsel;
  int nsel = 0;
  deselect_all_nodes(tgf->gf);

  select_all_sources(tgf->gf);
  lsel = get_list_selected_vertices(tgf->gf);
  nsel = count_llist(lsel);

  if(nsel > 1)
  {
    LNode_type *lsource = init_linked_list();
    LNode_type *ptr;
    PNODE bestroot = NULL;
    int maxr = 0;
    printf("More than 1 source\n");
    for(ptr = lsel->back; ptr!= lsel ; ptr= ptr->back)
    {
      root = (PNODE)ptr->info;
      Insert_linked_list(lsource, create_new_node_llist((char *)root));
    }
    deselect_all_nodes(tgf->gf);
    for(ptr = lsource->back; ptr!= lsource ; ptr= ptr->back)
    {
       int nst = 0;
       root = (PNODE)ptr->info;
       compute_tree_graph(tgf->gf,root);
       nst = select_tree(tgf->gf,root);
       if(nst > maxr)
       {
	 bestroot = root;
	 maxr = nst;
       }
       deselect_all_nodes(tgf->gf);
    }	
    Delete_all_list(lsource);
    root = bestroot;
    select_tree(tgf->gf,bestroot);
    printf("Best source node %d %s\n", root->num, root->label);
  }
  else if(nsel == 1) 
  {
    root = (PNODE)lsel->back->info;
    compute_tree_graph(tgf->gf,root);
    select_tree(tgf->gf,root);
  }

  if(root)
      printf("ROOT SOURCE %d %s\n", root->num, root->label);

  return root;
}


PNODE
choose_lowest_id_number(tgrFrame *tgf)
{
  LNode_type *lver = get_list_vertices(tgf->gf);
  LNode_type *ptr = NULL; 
  PNODE v = NULL;
  PNODE root = NULL;
  int nver = get_count_vertex(tgf->gf);
  int mid = -1;
  if(lver->back!=lver)
  {
    root = (PNODE)lver->back->info;
    mid = get_vertex_number(root);
  }
  for(ptr = lver->back; ptr!= lver ; ptr= ptr->back)
  {
    int id;
    v = (PNODE)ptr->info;
    id = get_vertex_number(root);
    if(id < mid)
    {
      root = v;
      mid = id;
    }
  }
  if(root)
  {
    int nst;
    printf("Lowest id vertex %d %s\n", root->num, root->label);
    deselect_all_nodes(tgf->gf);
    compute_tree_graph(tgf->gf,root);
    nst = select_tree(tgf->gf,root);
    if(nst < nver)
    {
      printf("Sorry %d is lower than %d root is null\n",nst, nver);
      root = NULL;
    }
  }
  return root;
}

PNODE
choose_biggest_hub_vertex(tgrFrame *tgf)
{
  PNODE root = NULL;
  LNode_type *lsel;
  LNode_type *ptr = NULL; 
  int maxiter = MAX_ITER;
  deselect_all_nodes(tgf->gf);
  compute_author_hub(tgf->gf, maxiter,NORM);
  select_big_hub(tgf->gf, 1);
  lsel = get_list_selected_vertices(tgf->gf);

  for(ptr = lsel->back; ptr!= lsel ; ptr= ptr->back)
  {
     root = (PNODE)ptr->info;
     printf("BIGGEST HUBS %d %s\n", root->num, root->label);
  }

  for(ptr = lsel->back; ptr!= lsel ; ptr= ptr->back)
  {
    root = (PNODE)ptr->info;
    break;
  }
  if(root)
  {
    int nst = 0;
    int nver = get_count_vertex(tgf->gf);
    printf("Biggest Hub vertex %d %s\n", root->num, root->label);
    deselect_all_nodes(tgf->gf);
    compute_tree_graph(tgf->gf,root);
    nst = select_tree(tgf->gf,root);
    if(nst < nver)
    {
      printf("Sorry %d is lower than %d root is null\n",nst, nver);
      root = NULL;
    }
  }
  return root;
}

PNODE
choose_best_root_vertex(tgrFrame *tgf)
{
  PNODE root = NULL;
  int nn = get_count_vertex(tgf->gf);
  int snodes = 0;

  root = choose_best_source_node(tgf);

  if(root) 
  {
    snodes = count_llist(get_list_selected_vertices(tgf->gf));  
    if(snodes != nn)
	return NULL;
  }

  if(root)
      printf("selecting root %d %s\n", root->num, root->label);

  if (root) return root;
  
  root = choose_biggest_hub_vertex(tgf);
  if(root)
      printf("selecting biggest hub %d %s\n", root->num, root->label);

  if(root)
      printf("selecting root %d %s\n", root->num, root->label);
  else
      printf("ROOT was not found\n");

  {

      printf("ROOT selected nodes %d from %d nodes\n", snodes,nn);
  }

  return root;
}
/****************************************************************************/

PNODE
create_node_map(tgrFrame *maptgf, iCluster *vc)
{
  PNODE v;
  char *label = vc->graphfile;
  char strcv[10];

  sprintf(strcv,"%d",vc->nnodes);
  v = create_node_in_graph_name(maptgf->gf, label);
  change_weight_vertex(maptgf->gf, v, strcv);

  set_vertex_shape(v, HEXAGON);
  add_attribute(v, "ROOT_URL",vc->vlabel);
  add_attribute(v, "title",vc->vtitle);

  return v;
}

void
construct_map_clusters(mainFrame *mf,tgrFrame *tgf,Hashtable_type FT)
{
  tgrFrame *maptgf = NULL;
  LNode_type *lvertices = get_list_vertices(tgf->gf);	
  LNode_type *ptr = NULL;

  maptgf = create_directed_graph(mf);


  for(ptr = lvertices->back; ptr != lvertices ; ptr = ptr->back)
  {
    PNODE v = (PNODE)ptr->info;
    char *vlabel = get_label_vertex(v);
    iCluster *vc = (iCluster*)get_element_hashed(FT, (Key_type)vlabel);
    char *vfile = vc ? vc->graphfile : NULL;
    LNode_type *peo = NULL, *ledges_out = get_edges_out(v);
    for(peo = ledges_out->back ; peo != ledges_out ; peo = peo->back)
    {
      PEDGE e = (PEDGE)peo->info;
      PNODE u = get_to_vertex(e);
      char *ulabel = get_label_vertex(u);
      iCluster *uc = (iCluster*)get_element_hashed(FT, (Key_type)ulabel);
      PEDGE ne = NULL;
      char *ufile = uc ? uc->graphfile : NULL;

      if(vfile != ufile)
      {
        PNODE mv = find_vertex_by_name(maptgf->gf,vfile);
        PNODE mu = find_vertex_by_name(maptgf->gf,ufile);

	if(!mv)
	{
	   printf("Creating %s\n", vfile);

	   mv = create_node_map(maptgf, vc);
	}
	if(!mu)
	{
	   printf("Creating %s\n", ufile);
	    mu = create_node_map(maptgf, uc);
	}
	ne = find_edge(maptgf->gf,mv,mu);
	if(!ne)
	  adding_edge(maptgf->gf,mv,mu,"1");
      }

    }
  }

  maptgf->root = find_orig_root(maptgf,tgf);
  if(!maptgf->root)
      maptgf->root = choose_best_root_vertex(maptgf);
  if(maptgf->root)
  {
    set_vertex_position(maptgf->root, GR_MWIDTH/2, 20);
    compute_tree_positions(maptgf->gf,maptgf->root,NORTH);
  }

  if(!maptgf->filename)
  {
    maptgf->filename = malloc(strlen(mf->basename)+10);
    if(!maptgf->filename) {
	fprintf(stderr,"Out of Memory construct_map_clusters\n");
	abort();
    }	
    sprintf(maptgf->filename, "%smap.gr", mf->basename);
  }

  save_current_graph(maptgf);
  {
    char *nf= malloc(strlen(mf->basename)+15);
    if(!nf) {
	fprintf(stderr,"Out of Memory construct_map_clusters\n");
	abort();
    }	
    sprintf(nf, "%smap.html", mf->basename);
    report_map_site(mf, maptgf, nf, maptgf->root, 0, 0, 0);
    free(nf); nf = NULL;
  }
}


void 
copy_root(tgrFrame *tgf, tgrFrame *ntgf)
{
  if(tgf->root) {
      printf("Root is %d %s\n", tgf->root->num, tgf->root->label);
      ntgf->root = find_vertex_by_name(ntgf->gf,get_label_vertex(tgf->root));
      set_root_vertex(ntgf->gf,ntgf->root);
  }
}

PNODE
find_orig_root(tgrFrame *maptgf,tgrFrame *tgf)
{
  LNode_type *ptr = NULL;
  LNode_type *lvertices = get_list_vertices(maptgf->gf);
  char *rlabel = NULL;
  if(!tgf->root)
    return NULL;

  rlabel = get_label_vertex(tgf->root);

  if(!rlabel)
      return NULL;

  for(ptr = lvertices->back; ptr != lvertices ; ptr = ptr->back)
  {
    PNODE mv = (PNODE)ptr->info;
    char *rurl = (char *)get_attribute(mv,"ROOT_URL");
    printf("RURL %s\n", rurl);
    if(rurl && !strcmp(rurl,rlabel))
	return mv;
  }
  return NULL;
}

FILE *
assert_open_text_file(const char *name_file)
{
  FILE *fp;
  if(!name_file)
    {
      fprintf(stderr, "File name is missing\n");
      return NULL;
    }
  fp = fopen(name_file, "w+");
  if(!fp)
    {
      fprintf(stderr, "Can't open %s \n",name_file);
      return NULL;
    }
  return fp;
}

long
my_simple_weight_edge(PEDGE e)
{
  return (1);
}

void
write_matrix_shortest_paths(tgrFrame *tgf, char *filename)
{
    FILE *fp = assert_open_text_file(filename);
    GraphFrame *gf = tgf->gf;
    long (*comp_weight)();
    LNode_type *lver = get_list_vertices(gf);
    LNode_type *ptr = NULL;
    LNode_type *ptrj = NULL;
    long c = 0;    

    comp_weight = my_simple_weight_edge;

    for(ptr = lver->back; ptr!=lver; ptr=ptr->back)
    {
	PNODE v = (PNODE)ptr->info;
	Dijkstra(gf,v,comp_weight);
	for(ptrj = lver->back; ptrj!=lver; ptrj=ptrj->back)
	{
	    PNODE u = (PNODE)ptrj->info;
	    c = get_value_shortest_path(u);
	    fprintf(fp,"%ld ",c);
	}
	fprintf(fp,"%s\n",get_label_vertex(v));
    }	
    fclose(fp);
}



